﻿#include "stdafx.h"
#include "DIPxuzz.h"

#include "DIPxuzzDoc.h"
#include "DIPxuzzView.h"
#include "mainfrm.h"
//#include "ColorTable.h"
#include "math.h"

#define PI 3.14159265
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

unsigned char* mark;
unsigned char* rmark, * gmark, * bmark;
int Wmark;
int Hmark;


/////////////////////////////////////////////////////////////////////////////
// CDipXuzzView

IMPLEMENT_DYNCREATE(CDipXuzzView, CScrollView)

BEGIN_MESSAGE_MAP(CDipXuzzView, CScrollView)
    //{{AFX_MSG_MAP(CDipXuzzView)
    ON_COMMAND(ID_GEOM_TRAN, OnGeomTran)
    ON_COMMAND(ID_GEOM_ROTA, OnGeomRota)
    ON_COMMAND(ID_GEOM_ZOOM, OnGeomZoom)
    ON_COMMAND(ID_POINT_INVERT, OnPointInvert)
    ON_COMMAND(ID_POINT_EQUA, OnPointEqua)
    ON_COMMAND(ID_FILE_256ToGray, OnColorToGray)
    ON_COMMAND(ID_EDGE_GAUSS, OnEdgeGauss)
    ON_COMMAND(ID_EDGE_PREWITT, OnEdgePrewitt)
    ON_COMMAND(ID_EDGE_ROBERT, OnEdgeRobert)
    ON_COMMAND(ID_EDGE_SOBEL, OnEdgeSobel)
    ON_COMMAND(ID_DETECT_THRESHOLD, OnDetectThreshold)
    ON_COMMAND(ID_EDGE_CONTOUR, OnEdgeContour)
    ON_COMMAND(MeasureHL, OnMeasureHL)
    //}}AFX_MSG_MAP
    // Standard printing commands
    ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
    ON_COMMAND(ID_Filter, &CDipXuzzView::OnFilter)
    ON_COMMAND(ID_Demo, &CDipXuzzView::OnDemo)
    ON_COMMAND(ID_DemoColor, &CDipXuzzView::OnDemocolor)
    ON_COMMAND(ID_WATERMARK_MARK, &CDipXuzzView::OnReadMark)
    ON_COMMAND(ID_WATERMARK_COMBINE, &CDipXuzzView::OnWatermarkCombine)
    ON_COMMAND(ID_FIRSTMENU_SECONDMENU, &CDipXuzzView::OnSecondmenu)
    ON_COMMAND(ID_GrayTrans, &CDipXuzzView::OnGraytrans)
    ON_COMMAND(ID_ColorChange, &CDipXuzzView::OnColorchange)
    ON_COMMAND(ID_AddNoise, &CDipXuzzView::OnAddnoise)
    ON_COMMAND(ID_watermark1, &CDipXuzzView::OnWatermark1)
    ON_COMMAND(ID_watermark2, &CDipXuzzView::OnWatermark2)
    ON_COMMAND(ID_Hide, &CDipXuzzView::OnHide)
    ON_COMMAND(ID_Find, &CDipXuzzView::OnFind)
    //	ON_COMMAND(ID_OLE_EDIT_CONVERT, &CDipXuzzView::OnOleEditConvert)
    ON_COMMAND(ID_OLE_EDIT_CONVERT, &CDipXuzzView::OnDemo_1)
    ON_COMMAND(ID_FruitLocation, &CDipXuzzView::OnFruitlocation)
    ON_COMMAND(ID_LaneDetection, &CDipXuzzView::OnLanedetection)
    ON_COMMAND(ID_Mosaic, &CDipXuzzView::OnMosaic)
    //	ON_WM_MENURBUTTONUP()
    //	ON_WM_MBUTTONDOWN()
    //	ON_WM_MBUTTONUP()
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
    ON_COMMAND(ID_ThinBody, &CDipXuzzView::OnThinbody)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDipXuzzView construction/destruction

CDipXuzzView::CDipXuzzView()
{
    // TODO: add construction code here

    switch_show = false;
}

CDipXuzzView::~CDipXuzzView()
{
}

BOOL CDipXuzzView::PreCreateWindow(CREATESTRUCT& cs)
{
    // TODO: Modify the Window class or styles here by modifying
    //  the CREATESTRUCT cs

    return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CDipXuzzView drawing

void CDipXuzzView::OnDraw(CDC* pDC)
{
    BeginWaitCursor();
    CDipXuzzDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);


    HDIB hDIB = pDoc->GetHDIB();
    // 判断DIB是否为空
    if (hDIB != NULL)
    {
        LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)hDIB);
        int cxDIB = (int) ::DIBWidth(lpDIB);
        int cyDIB = (int) ::DIBHeight(lpDIB);

        ::GlobalUnlock((HGLOBAL)hDIB);

        CRect rcDIB;
        rcDIB.top = rcDIB.left = 0;
        rcDIB.right = cxDIB;
        rcDIB.bottom = cyDIB;

        CRect rcDest;
        rcDest = rcDIB;

        // 输出DIB
        ::PaintDIB(pDC->m_hDC, &rcDest, pDoc->GetHDIB(), &rcDIB, pDoc->GetDocPalette());
    }


    // 恢复正常光标
    EndWaitCursor();
}


/////////////////////////////////////////////////////////////////////////////
// CDipXuzzView diagnostics

#ifdef _DEBUG
void CDipXuzzView::AssertValid() const
{
    CView::AssertValid();
}

void CDipXuzzView::Dump(CDumpContext& dc) const
{
    CView::Dump(dc);
}

CDipXuzzDoc* CDipXuzzView::GetDocument() // non-debug version is inline
{
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDipXuzzDoc)));
    return (CDipXuzzDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CDipXuzzView message handlers



LRESULT CDipXuzzView::OnDoRealize(WPARAM wParam, LPARAM)
{
    ASSERT(wParam != NULL);

    // 获取文档
    CDipXuzzDoc* pDoc = GetDocument();

    // 判断DIB是否为空
    if (pDoc->GetHDIB() == NULL)
    {
        // 直接返回
        return 0L;
    }

    // 获取Palette
    CPalette* pPal = pDoc->GetDocPalette();
    if (pPal != NULL)
    {
        // 获取MainFrame
        CMainFrame* pAppFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
        ASSERT_KINDOF(CMainFrame, pAppFrame);

        CClientDC appDC(pAppFrame);

        // All views but one should be a background palette.
        // wParam contains a handle to the active view, so the SelectPalette
        // bForceBackground flag is FALSE only if wParam == m_hWnd (this view)
        CPalette* oldPalette = appDC.SelectPalette(pPal, ((HWND)wParam) != m_hWnd);

        if (oldPalette != NULL)
        {
            UINT nColorsChanged = appDC.RealizePalette();
            if (nColorsChanged > 0)
                pDoc->UpdateAllViews(NULL);
            appDC.SelectPalette(oldPalette, TRUE);
        }
        else
        {
            TRACE0("\tCCh1_1View::OnPaletteChanged中调用SelectPalette()失败！\n");
        }
    }

    return 0L;
}

void CDipXuzzView::OnInitialUpdate()
{
    CView::OnInitialUpdate();

    // TODO: Add your specialized code here and/or call the base class

}

void CDipXuzzView::CalcWindowRect(LPRECT lpClientRect, UINT nAdjustType)
{
    CScrollView::OnInitialUpdate();
    ASSERT(GetDocument() != NULL);

    SetScrollSizes(MM_TEXT, GetDocument()->GetDocSize());
}

void CDipXuzzView::OnActivateView(BOOL bActivate, CView* pActivateView,
    CView* pDeactiveView)
{
    CScrollView::OnActivateView(bActivate, pActivateView, pDeactiveView);

    if (bActivate)
    {
        ASSERT(pActivateView == this);
        OnDoRealize((WPARAM)m_hWnd, 0);   // same as SendMessage(WM_DOREALIZE);
    }
}



//////////////////////////////////////////////////////////////////////////////////////
//  图像点运算
//
void CDipXuzzView::OnPointInvert()
{




}



void CDipXuzzView::OnPointEqua()
{
    CClientDC dc(this);
    CDipXuzzDoc* pDoc = GetDocument();   //获得文档
    LPSTR lpDIB;                       //指向DIB的指针
    LONG lWidth, lHeight;                    //图像宽度和高度
    LONG lLineBytes;
    LPSTR lpDIBBits;                   //指向DIB的象素的指针
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lpDIBBits = ::FindDIBBits(lpDIB);
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8);

    if (::DIBNumColors(lpDIB) != 256)
    {
        MessageBox("目前只支持256色位图", "系统提示", MB_ICONINFORMATION | MB_OK);
        ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
        return;
    }
    BeginWaitCursor();


    unsigned char* lpSrc;
    int	i, j;
    float temp;
    float lCount[256];
    float Map[256];

    for (i = 0; i < 256; i++)
        lCount[i] = 0;
    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            //lpSrc = (unsigned char*)lpDIBBits + lLineBytes * j + i;
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i;
            lCount[*(lpSrc)]++;
        }
    }

    int ox, oy;
    if (0)
    {
        //draw raw histogram
        ox = 1450;  oy = 800;
        POINT p1, p2;

        dc.MoveTo(ox, oy);   dc.LineTo(ox + 300, oy);    //X轴
        dc.LineTo(ox + 290, oy + 5);  dc.MoveTo(ox + 300, oy);    dc.LineTo(ox + 290, oy - 5);   	//箭头  
        dc.MoveTo(ox, oy);   dc.LineTo(ox, oy - 400);   	//Y轴
        dc.LineTo(ox - 5, oy - 390);   dc.MoveTo(ox, oy - 400);    dc.LineTo(ox + 5, oy - 390);     	//箭头

        dc.TextOutA(ox, oy + 20, "0");   dc.TextOutA(ox + 255, oy + 20, "255");

        // sarching max lcount[];

        for (int k = 0; k < 256; k++)
        {
            dc.MoveTo(ox + k, oy);
            dc.LineTo(ox + k, oy - (lCount[k] * 0.05));
        }
    }//end of if(0)


    for (i = 0; i < 256; i++) {
        temp = 0;
        for (j = 0; j <= i; j++) {
            temp += 1.0 * lCount[j] / (lHeight * lWidth);
        }
        Map[i] = (int)(temp * 255 + 0.5);
    }


    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i;

            *lpSrc = Map[*lpSrc];

            dc.SetPixel(lWidth + 10 + i, j, RGB(*lpSrc, *lpSrc, *lpSrc));
        }
    }


    float fCount[256];
    for (i = 0; i < 256; i++)
        fCount[i] = 0;
    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i;
            //lpSrc = (unsigned char*)lpDIBBits + lLineBytes * j + i;
            fCount[*(lpSrc)]++;
        }
    }

    //int ox, oy;
    if (1)
    {
        //draw raw histogram
        ox = 800;  oy = 600;
        POINT p1, p2;

        dc.MoveTo(ox, oy);   dc.LineTo(ox + 300, oy);    //X轴
        dc.LineTo(ox + 290, oy + 5);  dc.MoveTo(ox + 300, oy);    dc.LineTo(ox + 290, oy - 5);   	//箭头
        dc.MoveTo(ox, oy);   dc.LineTo(ox, oy - 400);   	//Y轴
        dc.LineTo(ox - 5, oy - 390);   dc.MoveTo(ox, oy - 400);    dc.LineTo(ox + 5, oy - 390);     	//箭头

        dc.TextOutA(ox, oy + 20, "0");   dc.TextOutA(ox + 255, oy + 20, "255");

        // sarching max lcount[];

        for (int k = 0; k < 256; k++)
        {
            dc.MoveTo(ox + k, oy);
            dc.LineTo(ox + k, oy - (fCount[k] * 0.05));
        }
    }//end of if(0)


    pDoc->SetModifiedFlag(TRUE);
    //pDoc->UpdateAllViews(NULL);
    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    EndWaitCursor();


}

//////////////////////////////////////////////////////////////////////////////////////
//  图像几何变换
unsigned char WINAPI Interpolation(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, FLOAT x, FLOAT y)
{

    // 四个最临近象素的坐标(i1, j1), (i2, j1), (i1, j2), (i2, j2)
    LONG	i1, i2;
    LONG	j1, j2;
    unsigned char	f1, f2, f3, f4;
    unsigned char	f12, f34;

    LONG lLineBytes;
    lLineBytes = WIDTHBYTES(lWidth * 8);

    // 赋值
    float EXP = (FLOAT)0.0001;

    // 计算四个最临近象素的坐标
    i1 = (LONG)x;
    i2 = i1 + 1;
    j1 = (LONG)y;
    j2 = j1 + 1;

    // 根据不同情况分别处理
    if ((x < 0) || (x > lWidth - 1) || (y < 0) || (y > lHeight - 1))
    {
        return 255;
    }
    else
    {
        if (fabs(x - lWidth + 1) <= EXP)
        {
            if (fabs(y - lHeight + 1) <= EXP)
            {
                f1 = *((unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j1) + i1);
                return f1;
            }
            else
            {
                f1 = *((unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j1) + i1);
                f3 = *((unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j1) + i2);

                return ((unsigned char)(f1 + (y - j1) * (f3 - f1)));
            }
        }
        else if (fabs(y - lHeight + 1) <= EXP)
        {
            f1 = *((unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j1) + i1);
            f2 = *((unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j2) + i1);

            return ((unsigned char)(f1 + (x - i1) * (f2 - f1)));
        }
        else
        {
            f1 = *((unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j1) + i1);
            f3 = *((unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j2) + i1);
            f2 = *((unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j1) + i2);
            f4 = *((unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j2) + i2);

            f12 = (unsigned char)(f1 + (x - i1) * (f2 - f1));
            f34 = (unsigned char)(f3 + (x - i1) * (f4 - f3));

            return ((unsigned char)(f12 + (y - j1) * (f34 - f12)));
        }
    }
}

void CDipXuzzView::OnGeomTran()
{
    // 平移位图
    CDipXuzzDoc* pDoc = GetDocument();   //获得文档
    LPSTR lpDIB;                       //指向DIB的指针
    LONG lWidth, lHeight;                    //图像宽度和高度
    LONG lLineBytes;
    LPSTR lpDIBBits;                   //指向DIB的象素的指针
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lpDIBBits = ::FindDIBBits(lpDIB);
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8);

    if (::DIBNumColors(lpDIB) != 256)
    {
        MessageBox("目前只支持256色位图", "系统提示", MB_ICONINFORMATION | MB_OK);
        ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
        return;
    }
    BeginWaitCursor();

    unsigned char* lpSrc, * temp;
    int	i, j;
    temp = new BYTE[lHeight * lWidth];


    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i;
            temp[lWidth * j + i] = *lpSrc;
        }
    }

    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i;

            if (i - 70 >= 0 && j - 50 >= 0) {
                *lpSrc = temp[(j - 50) * lWidth + (i - 70)];
            }
            else
            {
                *lpSrc = 255;
            }
        }
    }
    delete temp;

    pDoc->SetModifiedFlag(TRUE);
    pDoc->UpdateAllViews(NULL);
}


void CDipXuzzView::OnGeomZoom()
{
    // 图像缩放
    CClientDC dc(this);

    CDipXuzzDoc* pDoc = GetDocument();
    LPSTR lpDIB;
    LPSTR lpDIBBits;
    LONG lLineBytes;
    long lWidth, lHeight;                    //图像宽度和高度
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lpDIBBits = ::FindDIBBits(lpDIB);
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8);

    unsigned char* lpSrc;
    int	i, j;

    // 判断是否是8-bpp位图（这里为了方便，只处理8-bpp位图的缩放，其它的可以类推）
    if (::DIBNumColors(lpDIB) != 256)
    {
        MessageBox("目前只支持256色位图的缩放！", "系统提示", MB_ICONINFORMATION | MB_OK);
        // 解除锁定
        ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
        return;
    }

    // 缩放比率
    float fXZoomRatio = 2.0 / 1;//0.5;
    float fYZoomRatio = 2.0 / 1;//0.5;


    // 创建新DIB
    HDIB hNewDIB = NULL;
    LONG	lNewWidth;
    LONG	lNewHeight;
    LONG	lNewLineBytes;
    LPSTR	lpNewDIB;
    LPSTR	lpNewDIBBits;

    unsigned char* lpDst;
    int i0, j0;

    lNewWidth = (LONG)(::DIBWidth(lpDIB) * fXZoomRatio + 0.5);
    lNewLineBytes = WIDTHBYTES(lNewWidth * 8);
    lNewHeight = (LONG)(lHeight * fYZoomRatio + 0.5);

    hNewDIB = (HDIB) ::GlobalAlloc(GHND, lNewLineBytes * lNewHeight + *(LPDWORD)lpDIB + ::PaletteSize(lpDIB));
    lpNewDIB = (char*)::GlobalLock((HGLOBAL)hNewDIB);
    memcpy(lpNewDIB, lpDIB, *(LPDWORD)lpDIB + ::PaletteSize(lpDIB));  	// 复制DIB信息头和调色板
    lpNewDIBBits = ::FindDIBBits(lpNewDIB);

    // 指向BITMAPINFO结构的指针
    LPBITMAPINFOHEADER lpbmi = (LPBITMAPINFOHEADER)lpNewDIB;
    LPBITMAPCOREHEADER lpbmc = (LPBITMAPCOREHEADER)lpNewDIB;
    if (IS_WIN30_DIB(lpNewDIB))
    {
        lpbmi->biWidth = lNewWidth;
        lpbmi->biHeight = lNewHeight;
    }
    else
    {
        lpbmc->bcWidth = (unsigned short)lNewWidth;
        lpbmc->bcHeight = (unsigned short)lNewHeight;
    }


    BeginWaitCursor();

    for (i = 0; i < lNewHeight; i++)
    {
        for (j = 0; j < lNewWidth; j++)
        {
            lpDst = (unsigned char*)lpNewDIBBits + lNewLineBytes * (lNewHeight - 1 - i) + j;
            i0 = (LONG)(i / fYZoomRatio + 0.5);
            j0 = (LONG)(j / fXZoomRatio + 0.5);
            if ((j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight))
            {
                lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i0) + j0;
                //最近邻
                *lpDst = *lpSrc;
                //双线性插值
                //*lpDst = Interpolation (lpDIBBits, lWidth, lHeight, j/fYZoomRatio, i/fXZoomRatio);
            }
            else
                *lpDst = 255;


        }
    }


    pDoc->ReplaceHDIB(hNewDIB);  // 替换DIB，同时释放旧DIB对象
    pDoc->InitDIBData();  // 更新DIB大小和调色板

    pDoc->SetModifiedFlag(TRUE);
    pDoc->UpdateAllViews(NULL);
    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    EndWaitCursor();
}

void CDipXuzzView::OnGeomRota()
{
    // 图像旋转
    CClientDC dc(this);

    CDipXuzzDoc* pDoc = GetDocument();
    LPSTR lpDIB;
    LPSTR lpDIBBits;
    LONG lLineBytes;
    long lWidth, lHeight;                    //图像宽度和高度
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lpDIBBits = ::FindDIBBits(lpDIB);
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8);

    unsigned char* lpSrc;
    int	i, j;

    // 判断是否是8-bpp位图（这里为了方便，只处理8-bpp位图的缩放，其它的可以类推）
    if (::DIBNumColors(lpDIB) != 256)
    {
        MessageBox("目前只支持256色位图的缩放！", "系统提示", MB_ICONINFORMATION | MB_OK);
        // 解除锁定
        ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
        return;
    }


    // 创建新DIB
    HDIB hNewDIB = NULL;
    LONG	lNewWidth;
    LONG	lNewHeight;
    LONG	lNewLineBytes;
    LPSTR	lpNewDIB;
    LPSTR	lpNewDIBBits;

    float	fRotateAngle = -3.54 * PI / 180;;
    float	fSina, fCosa;
    fSina = (float)sin((double)fRotateAngle);
    fCosa = (float)cos((double)fRotateAngle);

    // 计算原图的四个角的坐标（以图像中心为坐标系原点）
    // 源图四个角的坐标（以图像中心为坐标系原点）
    float	fSrcX1, fSrcY1, fSrcX2, fSrcY2, fSrcX3, fSrcY3, fSrcX4, fSrcY4;
    float	fDstX1, fDstY1, fDstX2, fDstY2, fDstX3, fDstY3, fDstX4, fDstY4;
    fSrcX1 = (float)(-(lWidth - 1) / 2);
    fSrcY1 = (float)((lHeight - 1) / 2);
    fSrcX2 = (float)((lWidth - 1) / 2);
    fSrcY2 = (float)((lHeight - 1) / 2);
    fSrcX3 = (float)(-(lWidth - 1) / 2);
    fSrcY3 = (float)(-(lHeight - 1) / 2);
    fSrcX4 = (float)((lWidth - 1) / 2);
    fSrcY4 = (float)(-(lHeight - 1) / 2);

    // 计算新图四个角的坐标（以图像中心为坐标系原点）
    fDstX1 = fCosa * fSrcX1 + fSina * fSrcY1;
    fDstY1 = -fSina * fSrcX1 + fCosa * fSrcY1;
    fDstX2 = fCosa * fSrcX2 + fSina * fSrcY2;
    fDstY2 = -fSina * fSrcX2 + fCosa * fSrcY2;
    fDstX3 = fCosa * fSrcX3 + fSina * fSrcY3;
    fDstY3 = -fSina * fSrcX3 + fCosa * fSrcY3;
    fDstX4 = fCosa * fSrcX4 + fSina * fSrcY4;
    fDstY4 = -fSina * fSrcX4 + fCosa * fSrcY4;

    lNewWidth = (LONG)(max(fabs(fDstX4 - fDstX1), fabs(fDstX3 - fDstX2)) + 0.5);
    lNewLineBytes = WIDTHBYTES(lNewWidth * 8);
    lNewHeight = (LONG)(max(fabs(fDstY4 - fDstY1), fabs(fDstY3 - fDstY2)) + 0.5);

    float	f1, f2;   // 两个常数，这样不用以后每次都计算了
    f1 = (float)(-0.5 * (lNewWidth - 1) * fCosa - 0.5 * (lNewHeight - 1) * fSina + 0.5 * (lWidth - 1));
    f2 = (float)(0.5 * (lNewWidth - 1) * fSina - 0.5 * (lNewHeight - 1) * fCosa + 0.5 * (lHeight - 1));



    unsigned char* lpDst;
    int i0, j0;


    hNewDIB = (HDIB) ::GlobalAlloc(GHND, lNewLineBytes * lNewHeight + *(LPDWORD)lpDIB + ::PaletteSize(lpDIB));
    lpNewDIB = (char*)::GlobalLock((HGLOBAL)hNewDIB);
    memcpy(lpNewDIB, lpDIB, *(LPDWORD)lpDIB + ::PaletteSize(lpDIB));
    lpNewDIBBits = ::FindDIBBits(lpNewDIB);

    // 指向BITMAPINFO结构的指针
    LPBITMAPINFOHEADER lpbmi = (LPBITMAPINFOHEADER)lpNewDIB;
    LPBITMAPCOREHEADER lpbmc = (LPBITMAPCOREHEADER)lpNewDIB;
    if (IS_WIN30_DIB(lpNewDIB))
    {
        lpbmi->biWidth = lNewWidth;
        lpbmi->biHeight = lNewHeight;
    }
    else
    {
        lpbmc->bcWidth = (unsigned short)lNewWidth;
        lpbmc->bcHeight = (unsigned short)lNewHeight;
    }


    BeginWaitCursor();

    for (i = 0; i < lNewHeight; i++)
    {
        for (j = 0; j < lNewWidth; j++)
        {
            lpDst = (unsigned char*)lpNewDIBBits + lNewLineBytes * (lNewHeight - 1 - i) + j;
            i0 = (LONG)(-((float)j) * fSina + ((float)i) * fCosa + f2 + 0.5);
            j0 = (LONG)(((float)j) * fCosa + ((float)i) * fSina + f1 + 0.5);
            if ((j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight))
            {
                lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i0) + j0;
                *lpDst = *lpSrc;
                //双线性插值
                //float fi = -((float) j) * fSina + ((float) i) * fCosa + f2;
                //float fj =  ((float) j) * fCosa + ((float) i) * fSina + f1;
                //*lpDst = Interpolation (lpDIBBits, lWidth, lHeight, fj, fi);
            }
            else
                *lpDst = 255;
        }
    }


    pDoc->ReplaceHDIB(hNewDIB);  // 替换DIB，同时释放旧DIB对象
    pDoc->InitDIBData();  // 更新DIB大小和调色板

    pDoc->SetModifiedFlag(TRUE);
    pDoc->UpdateAllViews(NULL);
    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    EndWaitCursor();

}



void CDipXuzzView::OnColorToGray()//灰度变换
{
    CDipXuzzDoc* pDoc = GetDocument();
    LPSTR lpDIB;
    LPSTR lpDIBBits;                //指向DIB的象素的指针
    LPSTR lpNewDIBBits;             //指向DIB灰度图图像(新图像)开始处象素的指针
    LONG lLineBytes;
    long lWidth, lHeight;                    //图像宽度和高度
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度


    unsigned char* lpSrc;          //指向原图像象素点的指针
    unsigned char* lpdest;         //指向目标图像象素点的指针

    unsigned  char* ired, * igreen, * iblue;
    int i, j;


    RGBQUAD* lpRGBquad;
    lpRGBquad = (RGBQUAD*)&lpDIB[sizeof(BITMAPINFOHEADER)]; //INFOHEADER后为调色板		

    int gray;
    if (::DIBNumColors(lpDIB) != 256)  //非256色位图将它灰度化
    {
        lLineBytes = WIDTHBYTES(lWidth * 8 * 3);//真彩色一个象素为3个字节
        lpdest = new  BYTE[lHeight * lWidth];
        lpDIBBits = (LPSTR)lpDIB + sizeof(BITMAPINFOHEADER);//指向DIB象素

        for (i = 0; i < lWidth; i++)
        {
            for (j = 0; j < lHeight; j++)
            {
                ired = (unsigned  char*)lpDIBBits + lLineBytes * j + i * 3 + 2;
                igreen = (unsigned  char*)lpDIBBits + lLineBytes * j + i * 3 + 1;
                iblue = (unsigned  char*)lpDIBBits + lLineBytes * j + i * 3 + 0;

                gray = (unsigned  char)((*ired) * 0.299 + (*igreen) * 0.588 + (*iblue) * 0.114);
                //gray  = (*ired)*0.5- (*igreen)*0.999 + (*iblue)*0.09;

                lpdest[j * lWidth + i] = (unsigned  char)gray;
            }
        }

        //需要做三件事情：1、修改INFOHEADER 2、增加调色板 3、修改原图像灰度值
        LPBITMAPINFOHEADER  lpBI;
        lpBI = (LPBITMAPINFOHEADER)lpDIB;
        lpBI->biBitCount = 8;

        //设置灰度调色板
        for (i = 0; i < 256; i++)
        {
            lpRGBquad[i].rgbRed = (unsigned char)i;
            lpRGBquad[i].rgbGreen = (unsigned char)i;
            lpRGBquad[i].rgbBlue = (unsigned char)i;
            lpRGBquad[i].rgbReserved = 0;
        }

        lpNewDIBBits = ::FindDIBBits(lpDIB);  //找到DIB图像象素起始位置
        lLineBytes = WIDTHBYTES(lWidth * 8);
        //修改灰度值
        for (i = 0; i < lWidth; i++)
        {
            for (j = 0; j < lHeight; j++)
            {
                lpSrc = (unsigned  char*)lpNewDIBBits + lLineBytes * j + i;
                *lpSrc = lpdest[j * lWidth + i];
            }
        }
        delete  lpdest;
    }


    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    pDoc->SetModifiedFlag(TRUE);
    pDoc->UpdateAllViews(NULL);

}

/////////////////////////////////////////////////////////////////////////////////////
//  边缘与轮廓


void CDipXuzzView::OnEdgeGauss()
{
    //Gauss边缘检测运算


}


void CDipXuzzView::OnEdgePrewitt()
{
    //Prewitt边缘检测运算



}

void CDipXuzzView::OnEdgeRobert()
{
    //Robert边缘检测运算



}

void CDipXuzzView::OnEdgeSobel()
{
    //Sobel边缘检测运算
    CClientDC dc(this);
    CDipXuzzDoc* pDoc = GetDocument();   //获得文档
    LPSTR lpDIB;                       //指向DIB的指针
    LONG lWidth, lHeight;                    //图像宽度和高度
    LONG lLineBytes;
    LPSTR lpDIBBits;                   //指向DIB的象素的指针
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lpDIBBits = ::FindDIBBits(lpDIB);
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8);

    if (::DIBNumColors(lpDIB) != 256)
    {
        MessageBox("目前只支持256色位图", "系统提示", MB_ICONINFORMATION | MB_OK);
        ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
        return;
    }
    BeginWaitCursor();

    unsigned char* lpSrc;
    int	i, j;
    unsigned char* temp;
    temp = new BYTE[lHeight * lWidth];

    //long x = lWidth / 2, y = lHeight / 2;

    for (j = 0; j < lHeight; j++)
    {
        for (i = 0; i < lWidth; i++)
        {
            lpSrc = (unsigned  char*)lpDIBBits + lLineBytes * j + i;
            temp[j * lWidth + i] = *lpSrc;
        }
    }


    int W = 1; //sobel算子3X3 
    int v, h;  //垂直方向、水平方向
    for (j = 0 + W; j < lHeight - W; j++)
    {
        for (i = 0 + W; i < lWidth - W; i++)
        {
            v = 0;
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (j - 1) + (i - 1);
            v -= *lpSrc;
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (j - 1) + i;
            v -= (*lpSrc) * 2;
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (j - 1) + (i + 1);
            v -= *lpSrc;
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (j + 1) + (i - 1);
            v += *lpSrc * 1;
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (j + 1) + i;
            v += (*lpSrc) * 2;
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (j + 1) + (i + 1);
            v += *lpSrc * 1;


            h = 0;
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (j - 1) + (i - 1);
            h -= *lpSrc;
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * j + (i - 1);
            h -= (*lpSrc) * 2;
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (j + 1) + (i - 1);
            h -= *lpSrc;
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (j - 1) + (i + 1);
            h += *lpSrc;
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * j + (i + 1);
            h += (*lpSrc) * 2;
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (j + 1) + (i + 1);
            h += *lpSrc;

            int g;
            g = sqrt(1.0 * v * v + h * h);//*0.2;
            if (g > 255) g = 255;

            temp[lWidth * j + i] = g;
            dc.SetPixel(lWidth + 10 + i, lHeight - 1 - j, RGB(g, g, g));
        }
    }

    for (j = 0; j < lHeight; j++)
    {
        for (i = 0; i < lWidth; i++)
        {
            lpSrc = (unsigned  char*)lpDIBBits + lLineBytes * j + i;
            *lpSrc = temp[j * lWidth + i];
        }
    }
    delete temp;



    pDoc->SetModifiedFlag(TRUE);
    //pDoc->UpdateAllViews(NULL);
    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    EndWaitCursor();
}


void CDipXuzzView::OnEdgeContour()
{
    //在二值图像上提取轮廓边缘



}


//////////////////////////////////////////////////////////////////////////////////////
//  图像分析
//


//阈值分割
void CDipXuzzView::OnDetectThreshold()
{
    CClientDC dc(this);
    CDipXuzzDoc* pDoc = GetDocument();   //获得文档
    LPSTR lpDIB;                       //指向DIB的指针
    LONG lWidth, lHeight;                    //图像宽度和高度
    LONG lLineBytes;
    LPSTR lpDIBBits;                   //指向DIB的象素的指针
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lpDIBBits = ::FindDIBBits(lpDIB);
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8);

    if (::DIBNumColors(lpDIB) != 256)
    {
        MessageBox("目前只支持256色位图", "系统提示", MB_ICONINFORMATION | MB_OK);
        ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
        return;
    }
    BeginWaitCursor();

    //BYTE bThre;
    //bThre = Otsu((unsigned char*)lpDIBBits, lWidth, lHeight, lLineBytes);
    //bThre = 200;

    unsigned char* lpSrc;
    int	i, j;
    int Th = 175;

    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i / 2;

            if (*lpSrc > Th)  //bThre
                *lpSrc = 255;
            else
                *lpSrc = 0;

            //dc.SetPixel(lWidth + 480 + 20 + i, lHeight - 1 - 593 + j, RGB(*lpSrc, *lpSrc, *lpSrc));
        }
    }
    pDoc->SetModifiedFlag(TRUE);
    pDoc->UpdateAllViews(NULL);
    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    EndWaitCursor();
}


float calibation = 90.0 / 33.3;//标定比例
void CDipXuzzView::OnMeasureHL()
{

    //代码示例
    CClientDC dc(this);
    CDipXuzzDoc* pDoc = GetDocument();   //获得文档
    LPSTR lpDIB;                       //指向DIB的指针
    LONG lWidth, lHeight;                    //图像宽度和高度
    LONG lLineBytes;
    LPSTR lpDIBBits;                   //指向DIB的象素的指针
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lpDIBBits = ::FindDIBBits(lpDIB);
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8);

    if (::DIBNumColors(lpDIB) != 256)
    {
        MessageBox("目前只支持256色位图", "系统提示", MB_ICONINFORMATION | MB_OK);
        ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
        return;
    }
    BeginWaitCursor();


    unsigned char* lpSrc;
    int	i, j;

    int top = 0, bottom = 0, left = 0, right = 0;//四个方向的点
    int black_point;//黑点

    //找最左面的点
    black_point = 0;//用来精确的,找到5个黑点才算是找到,防止图片非人像外有黑点误差

    //从上向下扫描
    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i;
            if ((*lpSrc) == 0)//找到第一个黑点
            {
                break;
            }
        }
        left = i;
    }

    //找到最右面的点
    for (i = lWidth; i > 0; i--)
    {
        for (j = 0; j < lHeight; j++)
        {
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i;
            if ((*lpSrc) == 0)//找到第一个黑点
            {
                break;
            }
        }
        right = i - 66;
    }

    //找到最上边的点
    for (j = 0; j < lHeight; j++)
    {
        for (i = 0; i < lWidth; i++)
        {
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
            if ((*lpSrc) == 0)//找到第一个黑点
            {
                break;
            }
        }
        top = j;
    }

    //找到最下边的点
    for (j = lHeight; j > 0; j--)
    {
        for (i = lWidth / 2; i < lWidth; i++)
        {
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
            if ((*lpSrc) == 0)//找到第一个黑点
            {
                break;
            }
        }
        bottom = j;
    }

    float BLength = (-(float)right + (float)left) * calibation;
    float BHeight = (-(float)bottom + (float)top) * calibation;

    CString ss;
    ss.Format("身高:%16.2f", BHeight);
    dc.TextOut(19, 382, ss);
    ss.Format("臂长:%16.2f", BLength);
    dc.TextOut(19, 382 + 30, ss);


    pDoc->SetModifiedFlag(TRUE);
    //pDoc->UpdateAllViews(NULL);
    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    EndWaitCursor();
}

#define N 3

void CDipXuzzView::OnFilter()
{
    CClientDC dc(this);
    CDipXuzzDoc* pDoc = GetDocument();   //获得文档
    LPSTR lpDIB;                       //指向DIB的指针
    LONG lWidth, lHeight;                    //图像宽度和高度
    LONG lLineBytes;
    LPSTR lpDIBBits;                   //指向DIB的象素的指针
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lpDIBBits = ::FindDIBBits(lpDIB);
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8);

    if (::DIBNumColors(lpDIB) != 256)
    {
        MessageBox("目前只支持256色位图", "系统提示", MB_ICONINFORMATION | MB_OK);
        ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
        return;
    }
    BeginWaitCursor();


    unsigned char* lpSrc;
    int	i, j;
    int flag = 1;


    unsigned char* temp;
    temp = new  BYTE[lHeight * lWidth];
    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            lpSrc = (unsigned  char*)lpDIBBits + lLineBytes * j + i;
            temp[j * lWidth + i] = *lpSrc;
        }
    }

    //均值滤波
    if (!flag) {
        int a[N * N], k = 0;
        for (i = 0 + N / 2; i < lWidth - N / 2; i++) {
            for (j = 0 + N / 2; j < lHeight - N / 2; j++) {
                lpSrc = (unsigned  char*)lpDIBBits + lLineBytes * j + i;
                k = 0;
                for (int x = i - N / 2; x <= i + N / 2; x++) {
                    for (int y = j - N / 2; y <= j + N / 2; y++) {
                        a[k] = temp[lWidth * y + x];
                        k++;
                    }
                }
                int s = 0;
                for (int z = 0; z < N * N; z++) {
                    s += a[z];
                }
                *lpSrc = 1.0 * s / (N * N);
                dc.SetPixel(lWidth + 10 + i, lHeight - 1 - j, RGB(*lpSrc, *lpSrc, *lpSrc));
            }
        }
    }

    //中值滤波
    if (flag) {
        int a[N * N], k = 0;
        for (i = 0 + N / 2; i < lWidth - N / 2; i++) {
            for (j = 0 + N / 2; j < lHeight - N / 2; j++) {
                lpSrc = (unsigned  char*)lpDIBBits + lLineBytes * j + i;
                k = 0;
                for (int x = i - N / 2; x <= i + N / 2; x++) {
                    for (int y = j - N / 2; y <= j + N / 2; y++) {
                        a[k] = temp[lWidth * y + x];
                        k++;
                    }
                }
                int t;
                for (int s = 0; s < N * N - 1; s++) {
                    for (int r = 0; r < N * N - 1; r++) {
                        if (a[r] > a[r + 1]) {
                            t = a[r];
                            a[r] = a[r + 1];
                            a[r + 1] = t;
                        }
                    }
                }

                *lpSrc = a[(N * N) / 2 + 1];
                dc.SetPixel(lWidth + 10 + i, lHeight - 1 - j, RGB(*lpSrc, *lpSrc, *lpSrc));
            }
        }
    }


    pDoc->SetModifiedFlag(TRUE);
    //pDoc->UpdateAllViews(NULL);
    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    EndWaitCursor();

}


int CDipXuzzView::Otsu(unsigned char* lpDIBBits, long lWidth, long lHeight, LONG lLineBytes)
{
    unsigned char* lpSrc;
    long i, j;

    long lCount[256];
    for (i = 0; i < 256; i++)
    {
        lCount[i] = 0;
    }

    for (i = 0; i < lHeight; i++)
    {
        for (j = 0; j < lWidth; j++)
        {
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * i + j;
            lCount[*(lpSrc)]++;
        }
    }


    int thresholdValue = 128;

    int k;
    int n, n1, n2;
    double m1, m2, sum, csum, fmax, sb;

    sum = csum = 0.0;
    n = 0;
    for (k = 0; k <= 255; k++)
    {
        sum += (double)k * (double)lCount[k];
        n += lCount[k];
    }
    //	if (!n) 	return (160); 

        // do the otsu global thresholding method 
    fmax = -1.0;
    n1 = 0;
    for (k = 0; k < 256; k++)
    {
        n1 += lCount[k];
        if (!n1) { continue; }
        n2 = n - n1;
        if (n2 == 0) { break; }

        csum += (double)k * lCount[k];
        m1 = csum / n1;
        m2 = (sum - csum) / n2;
        sb = (double)n1 * (double)n2 * (m1 - m2) * (m1 - m2);

        if (sb > fmax)
        {
            fmax = sb; thresholdValue = k;
        }
    }

    return thresholdValue;
}


void CDipXuzzView::OnDemo()
{
    //代码示例
    CDipXuzzDoc* pDoc = GetDocument();   //获得文档
    LPSTR lpDIB;                       //指向DIB的指针
    LONG lWidth, lHeight;                    //图像宽度和高度
    LONG lLineBytes;
    LPSTR lpDIBBits;                   //指向DIB的象素的指针
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lpDIBBits = ::FindDIBBits(lpDIB);
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8);

    if (::DIBNumColors(lpDIB) != 256)
    {
        MessageBox("目前只支持256色位图", "系统提示", MB_ICONINFORMATION | MB_OK);
        ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
        return;
    }
    BeginWaitCursor();


    unsigned char* lpSrc;
    int	i, j;


    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i;

            *lpSrc = 128;
        }
    }
    pDoc->SetModifiedFlag(TRUE);
    pDoc->UpdateAllViews(NULL);
    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    EndWaitCursor();
}


void CDipXuzzView::OnDemocolor()
{
    CDipXuzzDoc* pDoc = GetDocument();
    LPSTR lpDIB;
    LPSTR lpDIBBits;
    LONG lLineBytes;
    LONG lWidth, lHeight;
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8 * 3);//真彩色一个象素为3个字节
    lpDIBBits = (LPSTR)lpDIB + sizeof(BITMAPINFOHEADER);


    unsigned  char* ired, * igreen, * iblue;
    int i, j;


    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            ired = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 2;
            igreen = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 1;
            iblue = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 0;

            *ired = 127;
            *igreen = 0;
            *iblue = 100;
        }
    }


    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    pDoc->SetModifiedFlag(TRUE);
    pDoc->UpdateAllViews(NULL);
}


void CDipXuzzView::OnReadMark()      // 从demo/democolor复制
{
    CDipXuzzDoc* pDoc = GetDocument();   //获得文档
    LPSTR lpDIB;                       //指向DIB的指针
    LONG lWidth, lHeight;                    //图像宽度和高度
    LONG lLineBytes;
    LPSTR lpDIBBits;                   //指向DIB的象素的指针
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lpDIBBits = ::FindDIBBits(lpDIB);
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8);

    if (::DIBNumColors(lpDIB) != 256)
    {
        MessageBox("目前只支持256色位图", "系统提示", MB_ICONINFORMATION | MB_OK);
        ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
        return;
    }
    BeginWaitCursor();


    unsigned char* lpSrc;
    int	i, j;

    Wmark = lWidth;
    Hmark = lHeight;
    mark = new BYTE[Wmark * Hmark];


    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i;

            mark[Hmark * j + i] = *lpSrc;
        }
    }



    pDoc->SetModifiedFlag(TRUE);
    pDoc->UpdateAllViews(NULL);
    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    EndWaitCursor();

}


void CDipXuzzView::OnWatermarkCombine()//水印
{
    CDipXuzzDoc* pDoc = GetDocument();   //获得文档
    LPSTR lpDIB;                       //指向DIB的指针
    LONG lWidth, lHeight;                    //图像宽度和高度
    LONG lLineBytes;
    LPSTR lpDIBBits;                   //指向DIB的象素的指针
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lpDIBBits = ::FindDIBBits(lpDIB);
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8);

    if (::DIBNumColors(lpDIB) != 256)
    {
        MessageBox("目前只支持256色位图", "系统提示", MB_ICONINFORMATION | MB_OK);
        ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
        return;
    }
    BeginWaitCursor();



    unsigned char* lpBase, * lpMark;
    int i, j;
    int xcoor = 10;
    int ycoor = 10;
    for (i = 0; i < Wmark; i++)
    {
        for (j = 0; j < Hmark; j++)
        {
            lpMark = mark + Wmark * j + i;
            lpBase = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - (j + ycoor)) + (i + xcoor);
            if (*lpMark < 128)
            {
                *lpBase = (*lpBase) * 0.2 + (*lpMark) * 0.8;
            }

        }
    }


    pDoc->SetModifiedFlag(TRUE);
    pDoc->UpdateAllViews(NULL);
    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    EndWaitCursor();

}


void CDipXuzzView::OnSecondmenu()
{
    // TODO: 在此添加命令处理程序代码

    CClientDC dc(this);

    for (int i = 0; i < 100; i++)
        dc.SetPixel(i, i, RGB(255, 0, 0));

    dc.MoveTo(100, 100);   dc.LineTo(100, 200);

    dc.Ellipse(100, 160, 200, 200);

    dc.TextOutA(150, 150, "demo demo demo demo demo.....");


}


void CDipXuzzView::OnGraytrans()
{
    CClientDC dc(this);
    CDipXuzzDoc* pDoc = GetDocument();   //获得文档
    LPSTR lpDIB;                       //指向DIB的指针
    LONG lWidth, lHeight;                    //图像宽度和高度
    LONG lLineBytes;
    LPSTR lpDIBBits;                   //指向DIB的象素的指针
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lpDIBBits = ::FindDIBBits(lpDIB);
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8);

    if (::DIBNumColors(lpDIB) != 256)
    {
        MessageBox("目前只支持256色位图", "系统提示", MB_ICONINFORMATION | MB_OK);
        ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
        return;
    }
    BeginWaitCursor();


    unsigned char* lpSrc;
    int	i, j;
    int temp;


    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i;
            temp = *lpSrc;
            //temp = (*lpSrc) * (*lpSrc) / 5.0 + 20;//250.0;
            //if (temp > 255) temp = 255;
            //if (temp < 0) temp = 0;


            //temp = 255 - (*lpSrc - 255) * (*lpSrc - 255) / 255.0;    //y=a*x^2;
            if (temp > 235) temp = 255;
            if (temp < 40) temp = 40;


            if (temp > 128 && temp <= 255) {
                if (*lpSrc < 192)	temp = (*lpSrc) / 3.0;
                else temp = (*lpSrc - 192) * 3 + 64;
                temp = 255 - sqrt((float)255 * 255 - temp * 255);
                if (temp > 255)
                    *lpSrc = 255;
                else if (temp < 0)	*lpSrc = 0;
                else *lpSrc = temp;
            }
            else if (temp >= 0 && temp < 128) {
                temp = (*lpSrc - 100) * 5;
                if (temp > 255)	*lpSrc = 255;
                else if (temp < 0)	*lpSrc = 0;
                else *lpSrc = temp;
            }
            else {
                if (temp > 255)	*lpSrc = 255;
                else if (temp < 0)	*lpSrc = 0;
                else *lpSrc = temp;
            }

            *lpSrc = temp;
            //dc.SetPixel(lWidth);
            dc.SetPixel(lWidth + 10 + i, j, RGB(*lpSrc, *lpSrc, *lpSrc));
        }
    }

}


void CDipXuzzView::OnColorchange()
{


}




void CDipXuzzView::OnAddnoise()
{
    CDipXuzzDoc* pDoc = GetDocument();   //获得文档
    LPSTR lpDIB;                       //指向DIB的指针
    LONG lWidth, lHeight;                    //图像宽度和高度
    LONG lLineBytes;
    LPSTR lpDIBBits;                   //指向DIB的象素的指针
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lpDIBBits = ::FindDIBBits(lpDIB);
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8);

    if (::DIBNumColors(lpDIB) != 256)
    {
        MessageBox("目前只支持256色位图", "系统提示", MB_ICONINFORMATION | MB_OK);
        ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
        return;
    }
    BeginWaitCursor();


    unsigned char* lpSrc;
    int	i, j, noise;
    int flag = 0;

    //椒盐噪声----中值
    if (flag) {
        for (noise = 0; noise < 2000; noise++) {
            int px = rand() % lWidth;
            int py = rand() % lHeight;
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * py + px;
            *lpSrc = 255;//rand()%256;//0
        }
    }


    //高斯噪声----均值
    if (!flag) {
        srand((unsigned)time(NULL));
        double a, b;
        int mean = 0, sigma = 10;
        int gray;
        for (j = 0; j < lHeight; j++)
        {
            for (i = 0; i < lWidth; i++)
            {
                lpSrc = (unsigned char*)lpDIBBits + lLineBytes * j + i;
                a = (rand() + 1) * 1.0 / RAND_MAX;    b = (rand() + 1) * 1.0 / RAND_MAX;

                gray = *lpSrc + mean + sigma * sqrt(-2 * log(a)) * cos(2 * PI * b);//高斯分布
                if (gray > 255)  gray = 255;
                if (gray < 0)    gray = 0;

                *lpSrc = gray;
            }
        }
    }

    pDoc->SetModifiedFlag(TRUE);
    pDoc->UpdateAllViews(NULL);;
    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    EndWaitCursor();

}


void CDipXuzzView::OnWatermark1()
{
    CDipXuzzDoc* pDoc = GetDocument();
    LPSTR lpDIB;
    LPSTR lpDIBBits;
    LONG lLineBytes;
    LONG lWidth, lHeight;
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8 * 3);//真彩色一个象素为3个字节
    lpDIBBits = (LPSTR)lpDIB + sizeof(BITMAPINFOHEADER);


    unsigned  char* ired, * igreen, * iblue;
    int i, j;
    Wmark = lWidth;
    Hmark = lHeight;
    rmark = new BYTE[Wmark * Hmark];
    gmark = new BYTE[Wmark * Hmark];
    bmark = new BYTE[Wmark * Hmark];


    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            ired = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 2;
            igreen = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 1;
            iblue = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 0;

            rmark[Wmark * j + i] = *ired;
            gmark[Wmark * j + i] = *igreen;
            bmark[Wmark * j + i] = *iblue;

            /*if (!(*ired > 128 && *igreen > 128 && *iblue > 128)) {
                *ired = (*ired) * 0.5 + (*rmark) * 0.5;
                *igreen = (*igreen) * 0.5 + (*gmark) * 0.5;
                *iblue = (*iblue) * 0.5 + (*bmark) * 0.5;
            }*/
        }
    }


    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    pDoc->SetModifiedFlag(TRUE);
    pDoc->UpdateAllViews(NULL);

}


void CDipXuzzView::OnWatermark2()//彩色水印
{
    CDipXuzzDoc* pDoc = GetDocument();
    LPSTR lpDIB;
    LPSTR lpDIBBits;
    LONG lLineBytes;
    LONG lWidth, lHeight;
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8 * 3);//真彩色一个象素为3个字节
    lpDIBBits = (LPSTR)lpDIB + sizeof(BITMAPINFOHEADER);


    unsigned  char* ired, * igreen, * iblue;
    unsigned char* markred, * markgreen, * markblue;
    int i, j;
    int coorx = 220;  //480
    int coory = 220;  //400



    for (i = 0; i < Wmark; i++)
    {
        for (j = 0; j < Hmark; j++)
        {
            markred = rmark + Wmark * j + i;
            markgreen = gmark + Wmark * j + i;
            markblue = bmark + Wmark * j + i;

            ired = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - (j + coory)) + (i + coorx) * 3 + 2;
            igreen = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - (j + coory)) + (i + coorx) * 3 + 1;
            iblue = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - (j + coory)) + (i + coorx) * 3 + 0;

            if (!(*markred > 200 && *markgreen > 200 && *markblue > 200)) {
                *ired = (*ired) * 0.5 + (*markred) * 0.5;
                *igreen = (*igreen) * 0.5 + (*markgreen) * 0.5;
                *iblue = (*iblue) * 0.5 + (*markblue) * 0.5;
            }

        }
    }


    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    pDoc->SetModifiedFlag(TRUE);
    pDoc->UpdateAllViews(NULL);

}


void CDipXuzzView::OnHide()
{
    // TODO: 在此添加命令处理程序代码
    /*CDipXuzzDoc* pDoc = GetDocument();   //获得文档
    LPSTR lpDIB;                       //指向DIB的指针
    LONG lWidth, lHeight;                    //图像宽度和高度
    LONG lLineBytes;
    LPSTR lpDIBBits;                   //指向DIB的象素的指针
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lpDIBBits = ::FindDIBBits(lpDIB);
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8);

    if (::DIBNumColors(lpDIB) != 256)
    {
        MessageBox("目前只支持256色位图", "系统提示", MB_ICONINFORMATION | MB_OK);
        ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
        return;
    }
    BeginWaitCursor();



    unsigned char* lpBase, * lpMark, *lpSrc;
    int i, j;

    int xcoor = 430;
    int ycoor = 80;

    //可选的
    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i;

            if ((*lpSrc) % 2)
                *lpSrc = *lpSrc - (*lpSrc) % 2;
        }
    }


    for (i = 0; i < Wmark; i++)
    {
        for (j = 0; j < Hmark; j++)
        {
            lpMark = mark + Wmark * j + i;
            lpBase = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - (j + ycoor)) + (i + xcoor);
            if (*lpMark < 128)
            {
                *lpBase = *lpBase + 1;  //255;     //周围背景的颜色值 如：220
            }



        }
    }


    pDoc->SetModifiedFlag(TRUE);
    pDoc->UpdateAllViews(NULL);
    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    EndWaitCursor();
    */

    CDipXuzzDoc* pDoc = GetDocument();
    LPSTR lpDIB;
    LPSTR lpDIBBits;
    LONG lLineBytes;
    LONG lWidth, lHeight;
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8 * 3);//真彩色一个象素为3个字节
    lpDIBBits = (LPSTR)lpDIB + sizeof(BITMAPINFOHEADER);


    unsigned  char* ired, * igreen, * iblue, * lpMark;
    int i, j;


    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            ired = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 2;
            igreen = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 1;
            iblue = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 0;

            *igreen = (*igreen) - (*igreen) % 2;
        }
    }

    unsigned char* markred, * markgreen, * markblue;
    int coorx = 220;  //480
    int coory = 220;  //400



    for (i = 0; i < Wmark; i++)
    {
        for (j = 0; j < Hmark; j++)
        {
            lpMark = mark + Wmark * j + i;

            ired = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - (j + coory)) + (i + coorx) * 3 + 2;
            igreen = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - (j + coory)) + (i + coorx) * 3 + 1;
            iblue = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - (j + coory)) + (i + coorx) * 3 + 0;


            if (*lpMark < 128)
            {
                *igreen = *igreen + 1;  //255;     //周围背景的颜色值 如：220
            }

        }
    }

    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    pDoc->SetModifiedFlag(TRUE);
    pDoc->UpdateAllViews(NULL);


}


void CDipXuzzView::OnFind()
{
    // TODO: 在此添加命令处理程序代码
    CClientDC dc(this);
    /*CDipXuzzDoc* pDoc = GetDocument();   //获得文档
    LPSTR lpDIB;                       //指向DIB的指针
    LONG lWidth, lHeight;                    //图像宽度和高度
    LONG lLineBytes;
    LPSTR lpDIBBits;                   //指向DIB的象素的指针
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lpDIBBits = ::FindDIBBits(lpDIB);
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8);

    if (::DIBNumColors(lpDIB) != 256)
    {
        MessageBox("目前只支持256色位图", "系统提示", MB_ICONINFORMATION | MB_OK);
        ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
        return;
    }
    BeginWaitCursor();



    unsigned char *lpSrc;
    int i, j;


    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i;

            /*if (*lpSrc != 255) {
                *lpSrc = 128;
            }
            */

            /*if ((*lpSrc) % 2)
                *lpSrc = 255;
            else
                *lpSrc = 0;

            dc.SetPixel(lWidth + i + 2, j, RGB(*lpSrc, *lpSrc, *lpSrc));
        }
    }


    pDoc->SetModifiedFlag(TRUE);
    //pDoc->UpdateAllViews(NULL);
    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    EndWaitCursor();
    */

    CDipXuzzDoc* pDoc = GetDocument();
    LPSTR lpDIB;
    LPSTR lpDIBBits;
    LONG lLineBytes;
    LONG lWidth, lHeight;
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8 * 3);//真彩色一个象素为3个字节
    lpDIBBits = (LPSTR)lpDIB + sizeof(BITMAPINFOHEADER);


    unsigned  char* ired, * igreen, * iblue;
    int i, j;


    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            ired = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 2;
            igreen = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 1;
            iblue = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 0;

            if ((*igreen) % 2)
                *ired = *igreen = *iblue = 255;
            else
                *ired = *igreen = *iblue = 0;

            dc.SetPixel(lWidth + i + 2, j, RGB(*ired, *igreen, *iblue));
        }
    }


    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    pDoc->SetModifiedFlag(TRUE);
    //pDoc->UpdateAllViews(NULL);


}

//void CDipXuzzView::OnOleEditConvert()
//{
//	// TODO: 在此添加命令处理程序代码
//	CClientDC dc(this);
//	dc.MoveTo(100, 200);
//	dc.LineTo(300, 400);
//}


void CDipXuzzView::OnDemo_1() //图像反转
{
    // TODO: 在此添加命令处理程序代码
    CClientDC dc(this);
    CDipXuzzDoc* pDoc = GetDocument();   //获得文档
    LPSTR lpDIB;                       //指向DIB的指针
    LONG lWidth, lHeight;                    //图像宽度和高度
    LONG lLineBytes;
    LPSTR lpDIBBits;                   //指向DIB的象素的指针
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lpDIBBits = ::FindDIBBits(lpDIB);
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8);

    if (::DIBNumColors(lpDIB) != 256)
    {
        MessageBox("目前只支持256色位图", "系统提示", MB_ICONINFORMATION | MB_OK);
        ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
        return;
    }
    BeginWaitCursor();


    unsigned char* lpSrc, * lpDst;
    int	i, j;
    unsigned char t;

    for (i = 0; i < lWidth / 2; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i;
            lpDst = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + (lWidth - 1 - i);

            t = *lpSrc;
            *lpSrc = *lpDst;
            *lpDst = t;
        }
    }

    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i;
            dc.SetPixel(lWidth + 10 + i, lHeight - j, RGB(*lpSrc, *lpSrc, *lpSrc));//画
        }
    }

    pDoc->SetModifiedFlag(TRUE);
    //pDoc->UpdateAllViews(NULL);
    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    EndWaitCursor();
}


void CDipXuzzView::OnFruitlocation()
{
    // TODO: 在此添加命令处理程序代码
    CClientDC dc(this);
    CPen pen(PS_SOLID, 3, RGB(0, 0, 255));
    CPen* pOldPen = dc.SelectObject(&pen);
    CDipXuzzDoc* pDoc = GetDocument();
    LPSTR lpDIB;
    LPSTR lpDIBBits;
    LONG lLineBytes;
    LONG lWidth, lHeight;
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8 * 3);//真彩色一个象素为3个字节
    lpDIBBits = (LPSTR)lpDIB + sizeof(BITMAPINFOHEADER);


    /*unsigned  char* ired, * igreen, * iblue;
    int i, j;
    int l, r, b, t;
    int count = 0, cx = 0, cy = 0;

    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < 250; j++)
        {
            ired = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 2;
            igreen = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 1;
            iblue = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 0;

            if ((*ired > 160) && (*igreen > 170) && (*iblue > 105)) {
                count++;
                cx += i;
                cy += j;
            }
        }
    }

    cx = cx / count;
    cy = cy / count;
    int length = sqrt((float)count) * 0.5;

    l = cx - length;
    r = cx + length;
    b = cy + length;
    t = cy - length;

    dc.MoveTo(l, t);
    dc.LineTo(r, t);
    dc.LineTo(r, b);
    dc.LineTo(l, b);
    dc.LineTo(l, t);


    int l1, r1, b1, t1;
    int count1 = 0, cx1 = 0, cy1 = 0;
    for (i = 0; i < lWidth; i++)
    {
        for (j = 250; j < lHeight; j++)
        {
            ired = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 2;
            igreen = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 1;
            iblue = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 0;

            if ((*ired > 160) && (*igreen > 170) && (*iblue > 105)) {
                count1++;
                cx1 += i;
                cy1 += j;
            }
        }
    }

    cx1 = cx1 / count1;
    cy1 = cy1 / count1;
    int length1 = sqrt((float)count1) * 0.5;
    int redius1 = sqrt(1.0 * count1 / 3.14);

    l1 = cx1 - length1;
    r1 = cx1 + length1;
    b1 = cy1 + length1;
    t1 = cy1 - length1;

    dc.MoveTo(l1, t1);
    dc.LineTo(r1, t1);
    dc.LineTo(r1, b1);
    dc.LineTo(l1, b1);
    dc.LineTo(l1, t1);
    */


    unsigned  char* ired, * igreen, * iblue;
    int i, j;
    int l, r, b, t;
    int count = 0, cx = 0, cy = 0;
    int flag = 1;


    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            ired = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 2;
            igreen = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 1;
            iblue = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 0;

            if ((*ired > 128) && (*igreen > 0) && (*iblue > 0)) {
                //*ired = *igreen = *iblue = 0;
                count++;
                cx += i;
                cy += j;
            }

            //dc.SetPixel(lWidth + 10 + i, j, RGB(*ired, *igreen, *iblue));

        }
    }

    cx = cx / count;
    cy = cy / count;
    int length = sqrt((float)count) * 0.5;
    int redius = sqrt(1.0 * count / 3.14);

    if (flag) {
        l = cx - length;
        r = cx + length;
        b = cy + length;
        t = cy - length;

        dc.MoveTo(l, t);
        dc.LineTo(r, t);
        dc.LineTo(r, b);
        dc.LineTo(l, b);
        dc.LineTo(l, t);
    }

    else {
        for (float th = 0; th < 2 * 3.1415; th += 0.001) {
            dc.SetPixel(cx + redius * cos(th), cy + redius * sin(th), RGB(0, 0, 255));
            dc.SetPixel(cx + (redius + 1) * cos(th), cy + (redius + 1) * sin(th), RGB(0, 0, 255));
            dc.SetPixel(cx + (redius + 2) * cos(th), cy + (redius + 2) * sin(th), RGB(0, 0, 255));
        }
    }


    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    pDoc->SetModifiedFlag(TRUE);
    //pDoc->UpdateAllViews(NULL);
}


void CDipXuzzView::OnLanedetection()
{
    // TODO: 在此添加命令处理程序代码
    CClientDC dc(this);
    CPen pen(PS_SOLID, 3, RGB(0, 255, 0));
    CPen* pOldPen = dc.SelectObject(&pen);

    CDipXuzzDoc* pDoc = GetDocument();   //获得文档
    LPSTR lpDIB;                       //指向DIB的指针
    long lWidth;                       //图像宽度和高度
    long lHeight;
    LONG lLineBytes;
    LPSTR lpDIBBits;                   //指向DIB的象素的指针
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lpDIBBits = ::FindDIBBits(lpDIB);
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8);

    if (::DIBNumColors(lpDIB) != 256)
    {
        MessageBox("目前只支持256色位图", "系统提示", MB_ICONINFORMATION | MB_OK);
        ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
        return;
    }
    BeginWaitCursor();


    unsigned char* lpSrc;
    int	i, j;

    int angle, dist;
    int maxdist = sqrt((float)lWidth * lWidth + lHeight * lHeight);
    int mindist = 0 - maxdist;

    int* houghspace = (int*)malloc(180 * (maxdist - mindist) * sizeof(int));
    memset(houghspace, 0, 180 * (maxdist - mindist) * sizeof(int));

    //hough voting
    for (i = 0 + 5; i < lWidth - 5; i++)//ROI
    {
        for (j = 0 + 5; j < lHeight - 5; j++)//ROI
        {
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i;

            if (*lpSrc > 192)//亮度值
            {
                for (angle = 0; angle < 180; angle++)
                {
                    dist = i * cos(angle * PI / 180) + j * sin(angle * PI / 180);
                    houghspace[180 * (dist - mindist) + angle]++;
                }
            }
        }
    }
    //finding peak(parameters of lines)
    for (int line = 0; line < 2; line++)
    {
        int maxvalue = 0;
        int maxa = 0;
        int maxd = 0;
        for (angle = 0; angle < 180; angle++)
        {
            for (dist = mindist; dist < maxdist; dist++)
            {
                if (houghspace[(dist - mindist) * 180 + angle] > maxvalue)
                {
                    maxvalue = houghspace[(dist - mindist) * 180 + angle];
                    maxa = angle; maxd = dist;
                }
            }
        }


        //draw line
        dc.MoveTo(0, maxd / sin(maxa * 3.14159 / 180));
        //dc.LineTo(maxd/cos(maxa*3.14159/180), 0);
        dc.LineTo(lWidth, ((maxd - lWidth * cos(maxa * 3.14159 / 180)) / sin(maxa * 3.14159 / 180)));

        CString s;
        s.Format("%6d,%6d", maxa, maxd);
        dc.TextOutA((maxd - 120) * cos(maxa * 3.14159 / 180) + 30, (maxd + 60) * sin(maxa * 3.14159 / 180), s);

        //clear current peak
        int w = 10;
        for (angle = maxa - w; angle < maxa + w; angle++)
        {
            for (dist = maxd - w; dist < maxd + w; dist++)
            {
                houghspace[180 * (dist - mindist) + angle] = 0;
            }
        }

    }


    pDoc->SetModifiedFlag(TRUE);
    //	pDoc->UpdateAllViews(NULL);
    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    EndWaitCursor();
}

void CDipXuzzView::OnMosaic()
{
    // TODO: 在此添加命令处理程序代码
    CClientDC dc(this);
    CPen pen(PS_SOLID, 3, RGB(0, 0, 255));
    CPen* pOldPen = dc.SelectObject(&pen);
    CDipXuzzDoc* pDoc = GetDocument();
    LPSTR lpDIB;
    LPSTR lpDIBBits;
    LONG lLineBytes;
    LONG lWidth, lHeight;
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8 * 3);//真彩色一个象素为3个字节
    lpDIBBits = (LPSTR)lpDIB + sizeof(BITMAPINFOHEADER);


    unsigned  char* ired, * igreen, * iblue;
    unsigned  char* curred, * curgreen, * curblue;
    unsigned  char* dred, * dgreen, * dblue;

    int i, j;
    int l, r, t, b;
    int w = 15;
    int Y, Cb, Cr;

    int count = 0, cx = 0, cy = 0;
    int flag = 1;


    for (i = 0; i < lWidth / 2; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            curred = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 2;
            curgreen = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 1;
            curblue = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 0;

            Y = 0.257 * (*curred) + 0.504 * (*curgreen) + 0.098 * (*curblue) + 16;
            Cb = -0.148 * (*curred) - 0.291 * (*curgreen) + 0.439 * (*curblue) + 128;
            Cr = 0.439 * (*curred) - 0.368 * (*curgreen) - 0.071 * (*curblue) + 128;

            if (Cr > 133 && Cr < 173 && Cb > 77 && Cb < 127) {
                count++;
                cx += i;
                cy += j;
            }
        }
    }

    cx = cx / count;
    cy = cy / count;
    int length = sqrt((float)count) * 0.5;
    l = cx - length;
    r = cx + length;
    b = cy + length;
    t = cy - length - 20;

    for (i = l; i < r; i += w)
    {
        for (j = t; j < b; j += w)
        {
            dred = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 2;
            dgreen = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 1;
            dblue = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 0;

            for (int k = i; k < i + w; k++) {
                for (int h = j; h < j + w; h++) {

                    ired = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - h) + k * 3 + 2;
                    igreen = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - h) + k * 3 + 1;
                    iblue = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - h) + k * 3 + 0;

                    *ired = *dred;
                    *igreen = *dgreen;
                    *iblue = *dblue;
                }
            }
        }
    }

    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    pDoc->SetModifiedFlag(TRUE);
    pDoc->UpdateAllViews(NULL);
}


//void CDipXuzzView::OnMenuRButtonUp(UINT nPos, CMenu* pMenu)
//{
//	// 该功能要求使用 Windows 2000 或更高版本。
//	// 符号 _WIN32_WINNT 和 WINVER 必须 >= 0x0500。
//	// TODO: 在此添加消息处理程序代码和/或调用默认值
//
//	CScrollView::OnMenuRButtonUp(nPos, pMenu);
//}


//void CDipXuzzView::OnMButtonDown(UINT nFlags, CPoint point)
//{
//	// TODO: 在此添加消息处理程序代码和/或调用默认值
//
//	CScrollView::OnMButtonDown(nFlags, point);
//}


//void CDipXuzzView::OnMButtonUp(UINT nFlags, CPoint point)
//{
//	// TODO: 在此添加消息处理程序代码和/或调用默认值
//
//	CScrollView::OnMButtonUp(nFlags, point);
//}

int left, right, top, bottom;
void CDipXuzzView::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值


    left = point.x;
    top = point.y;

    CScrollView::OnLButtonDown(nFlags, point);
}


void CDipXuzzView::OnLButtonUp(UINT nFlags, CPoint point)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    CClientDC dc(this);
    CPen pen(PS_SOLID, 3, RGB(0, 0, 255));
    dc.SelectObject(&pen);
    right = point.x;
    bottom = point.y;
    dc.MoveTo(left, top);
    dc.LineTo(right, top);
    dc.LineTo(right, bottom);
    dc.LineTo(left, bottom);
    dc.LineTo(left, top);
    CScrollView::OnLButtonUp(nFlags, point);
}


void CDipXuzzView::OnThinbody()
{
    // TODO: 在此添加命令处理程序代码
    CClientDC dc(this);
    CPen pen(PS_SOLID, 3, RGB(0, 0, 255));
    CPen* pOldPen = dc.SelectObject(&pen);
    CDipXuzzDoc* pDoc = GetDocument();
    LPSTR lpDIB;
    LPSTR lpDIBBits;
    LONG lLineBytes;
    LONG lWidth, lHeight;
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHDIB());
    lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
    lHeight = ::DIBHeight(lpDIB); //DIB 高度
    lLineBytes = WIDTHBYTES(lWidth * 8 * 3);//真彩色一个象素为3个字节
    lpDIBBits = (LPSTR)lpDIB + sizeof(BITMAPINFOHEADER);


    unsigned  char* ired, * igreen, * iblue;
    unsigned  char* curred, * curgreen, * curblue;
    unsigned  char* red, * green, * blue;
    int i, j;
    int ii, jj;

    unsigned char* bakDIBBits = new BYTE[lWidth * (lHeight + 1) * 3];
    double cx = (right + left) / 2;
    double scale = (right - cx) * 1.0;

    for (i = 0; i < lWidth; i++)
    {
        for (j = 0; j < lHeight; j++)
        {
            curred = (unsigned  char*)bakDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 2;
            curgreen = (unsigned  char*)bakDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 1;
            curblue = (unsigned  char*)bakDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 0;

            ired = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 2;
            igreen = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 1;
            iblue = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 0;

            *curred = *ired;
            *curgreen = *igreen;
            *curblue = *iblue;

            dc.SetPixel(lWidth + 10 + i, j, RGB(*curred, *curgreen, *curblue));

        }
    }


    int begin = cx - scale > 0 ? cx - scale : 0;
    int end = cx + scale < lWidth ? cx + scale : lWidth - 1;

    for (i = begin; i <= end; i++) {
        for (j = 0; j < lHeight; j++) {
            red = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 2;
            green = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 1;
            blue = (unsigned  char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i * 3 + 0;

            ii = cx + atan((i - cx) / scale) * scale * 4.0 / PI;
            jj = j;

            ired = (unsigned  char*)bakDIBBits + lLineBytes * (lHeight - 1 - jj) + ii * 3 + 2;
            igreen = (unsigned  char*)bakDIBBits + lLineBytes * (lHeight - 1 - jj) + ii * 3 + 1;
            iblue = (unsigned  char*)bakDIBBits + lLineBytes * (lHeight - 1 - jj) + ii * 3 + 0;

            *red = *ired;
            *green = *igreen;
            *blue = *iblue;

            dc.SetPixel(i + lWidth + 10, j, RGB(*red, *green, *blue));
        }
    }

    ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
    pDoc->SetModifiedFlag(TRUE);
    //pDoc->UpdateAllViews(NULL);
}
